/**
 *	Nikolas Bram - 20104278
 *	Dennis Thomasen - 20103903
 *	Gruppe 3 - Aflevering 3 - Genaflevering
 **/

import java.io.IOException;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

public class MulticastQueueTotalOnlyTest {

	public static void wait(int secs) {
		try {
			Thread.currentThread().sleep(secs*1000);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	public static void main(String[] args) throws IOException{
		int testSize = 30;
		InetAddress localhost = InetAddress.getLocalHost();
		MulticastQueueTotalOnly<Integer>[] peer = new MulticastQueueTotalOnly[5];

		for (int p=0; p<5; p++) {
			peer[p] = new MulticastQueueTotalOnly<Integer>(); 
		}

		System.out.println("FORMING GROUP");

		// Let peer0 create a group.
		peer[0].createGroup(45440, MulticastQueue.DeliveryGuarantee.TOTAL);
		//		peer[0].printLog();
		wait(1);

		// Let peer1 join at peer0 
		peer[1].joinGroup(45441, new InetSocketAddress(localhost,45440), MulticastQueue.DeliveryGuarantee.TOTAL);
		//		peer[1].printLog();
		wait(1);

		// Let peer2 join at peer1 
		peer[2].joinGroup(45442, new InetSocketAddress(localhost,45441), MulticastQueue.DeliveryGuarantee.TOTAL);
		//		peer[2].printLog();
		wait(1);

		// Let peer3 join at peer2 
		peer[3].joinGroup(45443, new InetSocketAddress(localhost, 45442), MulticastQueue.DeliveryGuarantee.TOTAL);
		wait(1);

		// Let peer4 join at peer3
		peer[4].joinGroup(45444, new InetSocketAddress(localhost, 45443), MulticastQueue.DeliveryGuarantee.TOTAL);
		wait(1);

		System.out.println("BROADCASTING");

		// Let them all send at the same time. 
		for (int i=0; i<testSize; i++) {
			peer[i % 5].put(i);
		}

		wait(10);

		System.out.println("LEAVING GROUP");

		peer[3].leaveGroup();
		wait(1);

		peer[4].leaveGroup();
		wait(1);

		peer[2].leaveGroup();
		wait(1);

		peer[0].leaveGroup();		
		wait(1);

		peer[1].leaveGroup();
		wait(1);

		/* We now see what each peer received. We print it,
		 * and we also tabulate it, to check that they all
		 * received each message exactly once.
		 */
		ArrayList<String> result = new ArrayList();
		MulticastMessage msg;
		int counter = 0;
		
		while((msg = peer[0].get()) != null){
			if(msg instanceof MulticastMessagePayload){
				result.add(msg.toString());
			}
			System.out.println(msg.toString());
		}
//		result.set(2, "test"); //Just a test to see if this test is actually functional
		for (int p = 1; p<5; p++) {
			System.out.println("TESTING OUTPUT FROM PEER NR. "+p);
			wait(2);
			while ((msg = peer[p].get()) != null) {
				if(msg instanceof MulticastMessagePayload){
					if(!msg.toString().equals(result.get(counter))){
						System.out.println("TEST FAILED - DIFFERENT QUEUE ORDER");
						System.exit(1);
					}
					counter++;
				}
			}
			System.out.println("OUTPUT FROM PEER NR. "+p+" SUCCESFULLY TESTED");
			counter = 0;
		}

		//Adding one of the peers output to the general result
		System.out.println("\nTest result: OK!");
	}
}
